package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

public class NioClient {
    // 缓冲区容量大小
    private static int bufferCapacity = 4096;
    // 发送缓冲区
    private static ByteBuffer sendBuffer = ByteBuffer.allocate(bufferCapacity);
    // 接收缓冲区
    private static ByteBuffer recBuffer = ByteBuffer.allocate(bufferCapacity);
    // 标识数据
    private static AtomicInteger countSend = new AtomicInteger(0);
    // 服务器地址

    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        // 打开选择器
        Selector selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        // 连接
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888));

        while (true) {
            // 阻塞，直到有事件发生
            selector.select();
            Set<SelectionKey> selectionKeySet = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeySet.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                if (selectionKey.isConnectable()) {
                    System.out.println("client connect...");
                    SocketChannel client = (SocketChannel) selectionKey.channel();
                    if (client.isConnectionPending()) {
                        client.finishConnect();
                        System.out.println("client connect success");
                        // 发送数据
                        sendBuffer.put("Hello Server".getBytes());
                        sendBuffer.flip();
                        client.write(sendBuffer);
                    }
                    // 注册读事件
                    client.register(selector, SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
                    System.out.println(">>>>>>>>client OP_READ事件！");
                    SocketChannel client = (SocketChannel) selectionKey.channel();
                    int len = client.read(recBuffer);
                    if (len > 0) {
                        recBuffer.flip();
                        String text = new String(recBuffer.array(), 0, len);
                        System.out.println("客户端接收到服务端的数据" + text);
                        // 注册写事件
                        client.register(selector, SelectionKey.OP_WRITE);
                    }
                } else if (selectionKey.isWritable()) {
                    System.out.println(">>>>>>>>client OP_WRITE事件！");
                    // 清理发送缓冲区
                    sendBuffer.clear();
                    SocketChannel client = (SocketChannel) selectionKey.channel();
                    String sendText = "Msg send to Server" + countSend.getAndIncrement();
                    sendBuffer.put(sendText.getBytes());
                    sendBuffer.flip();
                    client.write(sendBuffer);
                    System.out.println("客户端发送数据给服务端" + sendText);
                    // 注册读事件
                    client.register(selector, SelectionKey.OP_READ);
                }
            }
        }
    }
}
